package cn.thoughtworks.school.services;

import cn.thoughtworks.school.entities.LogicQuiz;
import cn.thoughtworks.school.entities.User;
import cn.thoughtworks.school.entities.dto.AssignmentQuizData;
import cn.thoughtworks.school.repositories.LogicQuizRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class LogicQuizService {

    @Autowired
    private LogicQuizRepository logicQuizRepository;
    @Autowired
    private Utils utils;
    @Value("${logic-type}")
    private String type;
    @Autowired
    private UserCenterService userCenterService;

    public LogicQuiz createLogicQuiz(LogicQuiz quiz, User user) {
        Long organizationId = userCenterService.getUserCurrentOrganizationId(user.getId());
        quiz.setMakerId(user.getId());
        quiz.setIsAvailable(true);
        quiz.setOrganizationId(organizationId);
        quiz.setCreateTime(new Date());

        return logicQuizRepository.save(quiz);
    }

    public Page getLogicQuizzesPageable(Pageable pageable, Long id, Long userId, String description, User user) {
      Long organizationId = userCenterService.getUserCurrentOrganizationId(user.getId());
      Page<LogicQuiz> logicQuizPage = logicQuizRepository.findAll((Specification<LogicQuiz>) (root, query, criteriaBuilder) -> {
        List<Predicate> predicates = new ArrayList<>();
        predicates.add(criteriaBuilder.equal(root.get("organizationId").as(Long.class), organizationId));
        predicates.add(criteriaBuilder.equal(root.get("isAvailable").as(Boolean.class),true));

        if (Objects.nonNull(id)) {
          predicates.add(criteriaBuilder.equal(root.get("id").as(Long.class), id));
        }
        if (Objects.nonNull(userId)) {
          predicates.add(criteriaBuilder.equal(root.get("makerId").as(Long.class), userId));
        }
        if (Objects.nonNull(description)) {
          predicates.add(criteriaBuilder.like(root.get("description").as(String.class), "%" + description + "%"));
        }
        return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
      }, pageable);

      return  utils.format(logicQuizPage, pageable);
    }

  public List<AssignmentQuizData> copy(List<AssignmentQuizData> logicQuizzesData) {
    List<Long> ids = logicQuizzesData.stream().map(AssignmentQuizData::getQuizId).collect(Collectors.toList());
    List<LogicQuiz> logicQuizzes = logicQuizRepository.findByIdIn(ids);

    logicQuizzesData.forEach(quizData -> {
      LogicQuiz logicQuiz = logicQuizzes.stream()
        .filter(quiz -> quiz.getId().equals(quizData.getQuizId()))
        .findFirst().get();
      logicQuiz = LogicQuiz.copy(logicQuiz, quizData.getCreatorId(), quizData.getOrganizationId());
      logicQuizRepository.save(logicQuiz);
      quizData.setNewQuizId(logicQuiz.getId());
    });
    return logicQuizzesData;
  }
}
